/**
 * 列表单
 * 应用场景：系统监控-实时监控-设置
 *
 * @author wujianx
 * @createDate 2020-12-22
 */
import { MinusCircleOutlined } from '@ant-design/icons';
import { Button, Input } from 'antd';
import React from 'react';
import { JSONObject } from 'admin/schema/common';
import './style.scss';

/**
 * 列配置以及按钮文字
 */
export interface ColFormArg {
  col: ColFormItem[];
  btnCaption: string;
}

/**
 * 单项列详细配置
 */
export declare type ColFormItem = {
  /**
   * 列头名称
   */
  name: string;
  /**
   * 该列导出值的key
   */
  key: string;
  /**
   * 自定义输入控件
   * todo 尚未支持
   */
  inputBuilder?: () => JSX.Element;
  /**
   * 输入内容验证函数，return false时输入内容将会被放弃
   */
  verify?: (text: string | number) => boolean;
};

interface ColFormState {
  currentValue: JSONObject[];
}

/**
 * 列表单
 */
export class ColForm extends React.Component<ColFormArg, ColFormState> {
  private formConfig: ColFormArg;

  private keysArr: string[];

  private btnCaption: string;

  constructor(arg: ColFormArg) {
    super(arg);
    this.formConfig = arg;
    this.btnCaption = arg.btnCaption;
    const keysArr = (this.keysArr = arg.col.map(item => item.key));
    const initData: JSONObject = {};
    keysArr.forEach(item => {
      initData[item] = '';
    });
    this.state = {
      currentValue: [initData],
    };
  }

  /**
   * 获取控件值
   */
  public getValue(): JSONObject[] {
    return this.state.currentValue;
  }

  /**
   * 设置控件初始值
   */
  public setValue(val: JSONObject[]): void {
    this.setState({
      currentValue: val,
    });
  }

  /**
   * 输入监听事件
   */
  private handleChange(
    item: ColFormItem,
    index: number,
    e: React.ChangeEvent<HTMLInputElement>
  ): void {
    const val = e.target.value;
    const key = item.key;
    if (item.verify && !item.verify(val)) {
      return;
    }
    const copyArr = this.state.currentValue;
    copyArr[index][key] = val;
    this.setState({
      currentValue: copyArr,
    });
  }

  /**
   * 删除一行
   */
  private delItem(rowIndex: number): void {
    const copyArr = this.state.currentValue;
    copyArr.splice(rowIndex, 1);
    this.setState({
      currentValue: copyArr,
    });
  }

  /**
   * 新增一行
   */
  private addItem(): void {
    const copyArr = this.state.currentValue;
    const keysArr = this.keysArr;
    const fakeVal: JSONObject = {};
    keysArr.forEach(item => {
      fakeVal[item] = '';
    });
    copyArr.push(fakeVal);
    this.setState({
      currentValue: copyArr,
    });
  }

  render(): JSX.Element {
    const col = this.formConfig.col;
    const { currentValue } = this.state;
    const colWidth = 100 / (col.length + 1) + 5 + '%';
    const delIconStyle = {
      fontSize: '20px',
      color: '#3591ff',
      transform: 'translateY(5px)',
    };

    return (
      <>
        <div className="colform-form-header">
          {col.map((item, index) => {
            return (
              <div className="colform-form-col" style={{ width: colWidth }} key={index}>
                {item.name}
              </div>
            );
          })}
          <div className="colform-form-col" style={{ width: '30px' }}></div>
        </div>
        <div className="colform-form-body">
          {currentValue.map((val, rowIndex) => {
            return (
              <div className="colform-form-row" key={rowIndex}>
                {col.map((colIns, colIndex) => {
                  return (
                    <div className="colform-form-col" style={{ width: colWidth }} key={colIndex}>
                      <Input
                        value={currentValue[rowIndex][colIns.key]}
                        onChange={event => {
                          this.handleChange(colIns, rowIndex, event);
                        }}
                      />
                    </div>
                  );
                })}
                <div style={{ width: '30px' }}>
                  <MinusCircleOutlined
                    style={delIconStyle}
                    onClick={e => {
                      this.delItem(rowIndex);
                    }}
                  />
                </div>
              </div>
            );
          })}
        </div>
        <div className="colform-form-footer">
          <Button
            className="colform-form-addbtn"
            type="primary"
            onClick={() => {
              this.addItem();
            }}
          >
            {this.btnCaption}
          </Button>
        </div>
      </>
    );
  }
}
